package com.kaguya.flyweight;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 享元模式
 * 当系统有大量类似的对象，频繁的创建造成性能损耗
 * 享元模式：通过共享技术有效的支持大量细粒度的对象
 * 例如 String 线程池等 创建对象时将值放入常量池，再次取则从常量池中取，如果值发生改变则创建新对象
 * 对于多线程需要考虑线程安全问题，一致性 原子性
 */
public  class Test {
    public static void main(String[] args) {
        /**
         * 使用场景：一张地图需要根据坐标绘制许多几种类型的树，树的类型只有几种，但是数量很多
         */
        //绘制
        new TreeNode(45,18,TreeFactory.getTree("xxxx","xxxx"));
        new TreeNode(78,98,TreeFactory.getTree("xxxx","xxxx"));

        new TreeNode(7,86,TreeFactory.getTree("yy","yy"));
        new TreeNode(25,13,TreeFactory.getTree("yy","yy"));
    }
}

/**
 * 工厂类，处理树类的分享创建
 */
class TreeFactory {

    //管理实例池
    final static ConcurrentHashMap<String,Tree> map = new ConcurrentHashMap<>();


    static Tree getTree(String name,String data){
        //如果已经被创建 直接从其中取并返回
        if(map.containsKey(name)){
            System.out.println(name+" tree has been created!");
            return map.get(name);
        }
        //如果实例池中没有，则创建对象，加入实例池并返回
        Tree tree = new Tree(name, data);
        map.put(tree.getNAME(),tree);
        return tree;
    }
}

/**
 * 树节点类 其中一个属性为树类
 */
class TreeNode{
    private int x;
    private int y;
    private Tree tree;

    public TreeNode(int x, int y, Tree tree) {
        this.x = x;
        this.y = y;
        this.tree = tree;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public Tree getTree() {
        return tree;
    }

    public void setTree(Tree tree) {
        this.tree = tree;
    }
}
/**
 * 树类
 */
class Tree {
    private final String NAME;
    private final String DATA;

    public Tree(String NAME, String DATA) {
        this.NAME = NAME;
        this.DATA = DATA;
    }

    public String getNAME() {
        return NAME;
    }

    public String getDATA() {
        return DATA;
    }
}
